﻿namespace JunFan.Controllers
{
    using System.Collections.Generic;
    using System.Web.Mvc;
    using AutoMapper;
    using Domain;
    using ViewModels;

    public class ItemController : Controller
    {
        //
        // GET: /Item/

        public ActionResult Index()
        {
            var dashboardView = new ItemDashboardView
                {
                    BackLogItems = GetBacklogItems(),
                    InProgressItems = GetInProgressItems(),
                    CompletedItems = GetCompletedItems()
                };

            return View(dashboardView);
        }

        public ActionResult Add()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Add(ItemView itemView)
        {
            if (!ModelState.IsValid)
            {
                return View(itemView);
            }

            var board = new Board();
            
            var item = MapToDomain(itemView);
            board.AddItem(item);

            return RedirectToAction("Index");
        }

        public ActionResult Start(int id)
        {
            var board = new Board();
            board.StartItem(id);

            return RedirectToAction("Index");
        }

        public ActionResult Complete(int id)
        {
            var board = new Board();
            board.CompleteItem(id);

            return RedirectToAction("Index");
        }

        public ActionResult ValidateUniqueiId(string id)
        {
            var board = new Board();

            bool result = !board.ItemExists(new Item { Id = id });

            return Json(result, JsonRequestBehavior.AllowGet);
        }

        protected override void OnException(ExceptionContext filterContext)
        {
            if (filterContext.Exception is BusinessRuleException)
            {
                var e = (BusinessRuleException) filterContext.Exception;

                ModelState.AddModelError(e.Key, e.Message);

                filterContext.ExceptionHandled = true;
            }
            else if (filterContext.Exception is WrongArgumentException)
            {
                var e = (WrongArgumentException) filterContext.Exception;

                var model = new ArgumentExceptionErrorView(e);

                var result = new ViewResult
                {
                    ViewName = "ArgumentExceptionError",
                    ViewData = new ViewDataDictionary<ArgumentExceptionErrorView>(model),
                    TempData = filterContext.Controller.TempData
                };

                filterContext.Result = result;
                filterContext.ExceptionHandled = true;
            }
        }

        private IEnumerable<ItemView> GetCompletedItems()
        {
            var board = new Board();

            IEnumerable<Item> items = board.GetCompletedItems();

            var itemViews = MapToView(items);

            return itemViews;
        }

        private IEnumerable<ItemView> GetInProgressItems()
        {
            var board = new Board();

            IEnumerable<Item> items = board.GetInProgressItems();

            var itemViews = MapToView(items);
            
            return itemViews;
        }

        private IEnumerable<ItemView> GetBacklogItems()
        {
            var board = new Board();

            IEnumerable<Item> items = board.GetBacklogItems();

            var itemViews = MapToView(items);

            return itemViews;
        }

        private static Item MapToDomain(ItemView view)
        {
            return Mapper.Map<Item>(view);
        }

        private IEnumerable<ItemView> MapToView(IEnumerable<Item> items)
        {
            return Mapper.Map<IEnumerable<Item>, List<ItemView>>(items);
        }
    }
}
